#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>

#define NUM 10

typedef void (*func_t)(); //函数指针

func_t handlerTask[NUM];

//样例任务
void task1()
{
    printf("handler task1\n");
}
void task2()
{
    printf("handler task1\n");
}
void task3()
{
    printf("handler task1\n");
}

void loadTask()
{
    memset(handlerTask, 0, sizeof(handlerTask));
    handlerTask[0] = task1;
    handlerTask[1] = task2;
    handlerTask[2] = task3;
}

void addtask()
{}




int main()
{
    pid_t id = fork();
    assert(id != -1);
    if(id == 0)
    {
        //child
        int cnt = 10;
        while(cnt)
        {
            printf("child running, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt--);
            sleep(1);
        //    int *p = 0;
        //    *p = 100; //野指针问题
        }

        exit(10);
    }

    loadTask();
    // parent
    int status = 0;
    while(1)
    {
        pid_t ret = waitpid(id, &status, WNOHANG); //WNOHANG: 非阻塞-> 子进程没有退出, 父进程检测时候，立即返回
        if(ret == 0)
        {
            // waitpid调用成功 && 子进程没退出
            //子进程没有退出，我的waitpid没有等待失败，仅仅是监测到了子进程没退出.
            printf("wait done, but child is running...., parent running other things\n");
            for(int i = 0; handlerTask[i] != NULL; i++)
            {
                handlerTask[i](); //采用回调的方式，执行我们想让父进程在空闲的时候做的事情
            }
        }
        else if(ret > 0)
        {
            // 1.waitpid调用成功 && 子进程退出了
            printf("wait success, exit code: %d, sig: %d\n", (status>>8)&0xFF, status & 0x7F);
            break;
        }
        else
        {
            // waitpid调用失败
            printf("waitpid call failed\n");
        //    break;
        }
        sleep(1);
    }








    
    
    
    //int status = 0;
    //// 1. 让OS释放子进程的僵尸状态
    //// 2. 获取子进程的退出结果
    //// 在等待期间，子进程没有退出的时候，父进程只能阻塞等待
    //int ret = waitpid(id, &status, 0);
    //if(ret > 0)
    //{
    //    // 是否正常退出
    //    if(WIFEXITED(status))
    //    {
    //        // 判断子进程运行结果是否ok
    //        printf("exit code: %d\n", WEXITSTATUS(status));
    //    }
    //    else{
    //        //TODO
    //        printf("child exit not normal!\n");
    //    }
    //    //printf("wait success, exit code: %d, sig: %d\n", (status>>8)&0xFF, status & 0x7F);
    //}

    return 0;
}
